#include "cmdParser.h"
#include "utils.h"

bool isValidCMD(const char *cmd, CMD_TYPE *type) // 爽
{
    // TODO: 从配置文件中读取支持的命令列表
    char *supportCmds[]= {
        "cd", 
        "ls", 
        "pwd",
        "gets",
        "puts",
        "remove",
    };

    size_t len = COUNT_OF(supportCmds);

    for(size_t i = 0; i < len; i++) {
        if (strcmp(cmd, supportCmds[i]) == 0) {
            *type = (CMD_TYPE)i;
            return true;
        }
    }

    *type = INVALID_CMD;
    return false;
}

// cd命令处理
serv2clientMsg_t cdFunc(char **tokens) // 旭
{
    serv2clientMsg_t msg = {};
    return msg;
}

// ls命令处理
serv2clientMsg_t lsFunc(const char *absPath) // 爽
{
    serv2clientMsg_t msg = {
        .exec_status = false,
        .description = "执行失败!",
        .filedirs = NULL,
        .cwd = NULL,
    };

    struct dirent *entry;
    struct stat fileStat;
    DIR *dp = opendir(absPath);

    if (dp == NULL) {
        perror("opendir");
        return msg;
    }

    // 存放absPath目录下的所有文件、子目录信息
    fileinfos_t *fileinfosPtr = (fileinfos_t *)calloc(1, sizeof(fileinfos_t));

    while ((entry = readdir(dp)) != NULL) {
        char fullPath[1024];
        snprintf(fullPath, sizeof(fullPath), "%s/%s", absPath, entry->d_name);

        if (stat(fullPath, &fileStat) == -1) {
            perror("stat");
            continue;
        }

        /*
           printf("Name: %s\n", entry->d_name);
           printf("Type: %s\n", (S_ISDIR(fileStat.st_mode)) ? "Directory" : "File");
           printf("Size: %ld bytes\n", fileStat.st_size);
           printf("Permissions: %o\n", fileStat.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
           printf("Last Modified: %s\n", ctime(&fileStat.st_mtime));
           printf("\n");
        */

        fileinfo_node_t *fileinfoNodePtr = (fileinfo_node_t *)calloc(1, sizeof(fileinfo_node_t));
        fileinfoNodePtr->file_name = entry->d_name; 
        fileinfoNodePtr->file_type = (S_ISDIR(fileStat.st_mode)) ? DIRECTORY : NORMAL_FILE;
        fileinfoNodePtr->size = fileStat.st_size; 
        // fileinfoNodePtr->next = NULL; 
        // 头插法
        fileinfoNodePtr->next = fileinfosPtr->head; 
        fileinfosPtr->head = fileinfoNodePtr; 

        /*
           if (NULL == fileinfosPtr->head)
           fileinfosPtr->head = fileinfoNodePtr;
           else {
           fileinfoNodePtr->next = fileinfosPtr->head->next;
           fileinfoNodePtr->next = fileinfosPtr->head->next;

           }
           */

        fileinfosPtr->size++;
    }

    msg.exec_status = true;
    msg.description = "执行成功!";
    msg.filedirs = fileinfosPtr;
    msg.cwd = absPath;

    closedir(dp);

    return msg;
}

// puts命令处理,上传文件
serv2clientMsg_t putsFunc(char **tokens) // 旭
{
    serv2clientMsg_t msg;
    return msg;
}

// gets命令处理,下载文件
serv2clientMsg_t getsFunc(char **tokens) // 飞
{
    serv2clientMsg_t msg;
    return msg;
}

// remove命令处理
serv2clientMsg_t removeFunc(char **tokens) // 飞
{
    serv2clientMsg_t msg;
    return msg;
}

// pwd命令处理
serv2clientMsg_t pwdFunc(char **tokens) // 勇
{
    serv2clientMsg_t msg;
    return msg;
}

// mkdir命令处理
serv2clientMsg_t mkdirFunc(char **tokens,char* path,int size) // 旭
{
    serv2clientMsg_t msg;
    return msg;
}

// 无效命令响应
serv2clientMsg_t invalidFunc(char **tokens) // 飞
{
    serv2clientMsg_t msg;
    return msg;
}


/*
 * 单元测试函数实现，测试完成后需要删除
 * 创建人：曾爽
 * 创建事件：2024/07/06
 * */

void unitest_lsFunc(void) {
    char *path = "/home/tsang/";
    serv2clientMsg_t msg = lsFunc(path);    

    if (true == msg.exec_status) {
        printf("Desrciption: %s\n", msg.description);
        printf("cwd: %s\n", msg.cwd);
        printf("Total files: %d\n", msg.filedirs->size);
        fileinfo_node_t *p = msg.filedirs->head;
        while (p) {
            printf("File name: %s\n", p->file_name);
            printf("File size: %lu\n", p->size);
            printf("File type: %d\n", p->file_type);
            printf("\n");
            p = p->next;
        }

    } else {
        printf("执行失败\n");
    }
}
